package com.example.filemonitor;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.documentfile.provider.DocumentFile;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

public class FileMonitorService extends Service {
    private static final String TAG = "FileMonitorService";
    private static final String CHANNEL_ID = "FileMonitorChannel";
    private ScheduledExecutorService scheduler;
    private Handler handler;
    private Set<String> knownFiles = new HashSet<>();
    private Uri sourceUri;
    private Uri targetPicUri;
    private Uri targetVioUri;
    private SharedPreferences prefs;

    @Override
    public void onCreate() {
        super.onCreate();
        handler = new Handler(Looper.getMainLooper());
        prefs = getSharedPreferences("FileMonitorPrefs", MODE_PRIVATE);
        createNotificationChannel();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String sourceUriStr = intent.getStringExtra("source_uri");
            String tarPicUriStr = intent.getStringExtra("target_pic_uri");
            String tarVioUriStr = intent.getStringExtra("target_vio_uri");

            if (sourceUriStr != null && tarPicUriStr != null) {
                sourceUri = Uri.parse(sourceUriStr);
                targetPicUri = Uri.parse(tarPicUriStr);
                targetVioUri = Uri.parse(tarVioUriStr);

                // 显示前台通知，防止一加手机杀死服务
                startForeground(1, createNotification());
                
                // 初始化已知文件列表
                initializeKnownFiles();
                
                // 使用定时扫描替代FileObserver，适配一加手机
                startFileScanner();
            }
        }
        
        // 确保服务被杀死后能重启
        return START_STICKY;
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID,
                "文件监控服务",
                NotificationManager.IMPORTANCE_LOW
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            if (manager != null) {
                manager.createNotificationChannel(channel);
            }
        }
    }

    private Notification createNotification() {
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 0, notificationIntent, 
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0
        );

        return new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("文件监控中")
            .setContentText("正在监听文件夹变化")
            .setSmallIcon(android.R.drawable.stat_notify_sync)
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build();
    }

    private void initializeKnownFiles() {
        Executors.newSingleThreadExecutor().execute(() -> {
            knownFiles.clear();
            List<String> fileNames = listFiles(sourceUri);
            if (fileNames != null) {
                knownFiles.addAll(fileNames);
            }
        });
    }

    private void startFileScanner() {
        if (scheduler != null && !scheduler.isShutdown()) {
            scheduler.shutdown();
        }
        
        // 每3秒扫描一次，适配一加手机的文件系统响应
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(this::scanFiles, 0, 3, TimeUnit.SECONDS);
    }

    private void scanFiles() {
//        showToast("====扫描文件夹");
        try {
            List<String> currentFiles = listFiles(sourceUri);
            if (currentFiles == null) return;
            
            // 查找新文件
            for (String fileName : currentFiles) {
                if (!knownFiles.contains(fileName)) {
                    knownFiles.add(fileName);
                    copyNewFile(fileName);
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "扫描文件出错: " + e.getMessage());
        }
    }

    private List<String> listFiles(Uri uri) {
        DocumentFile sourceDir = DocumentFile.fromTreeUri(this, uri);
        if (sourceDir == null || !sourceDir.exists() || !sourceDir.isDirectory()) {
            showToast("源文件夹不可访问，请重新选择");
            return null;
        }

        List<String> fileNames = new ArrayList<>();
        DocumentFile[] files = sourceDir.listFiles();
        if (files != null) {
            for (DocumentFile file : files) {
                if (file.isFile()) {
                    fileNames.add(file.getName());
                }
            }
        }
        return fileNames;
    }

    private void copyNewFile(String fileName) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
        Date nowDate = new Date();
        String curTime = fmt.format(nowDate);
        String curDay = curTime.substring(0,8);
        String curHour = curTime.substring(0,10);
        String curMin = curTime.substring(0,12);

        // 10分钟 = 10 * 60 * 1000 毫秒
        long tenMinutesAgoTime = nowDate.getTime() - 10 * 60 * 1000;
        Date tenMinutesAgoDate = new Date(tenMinutesAgoTime);

        try {
            DocumentFile sourceDir = DocumentFile.fromTreeUri(this, sourceUri);
            DocumentFile tarPicDir = DocumentFile.fromTreeUri(this, targetPicUri);
            DocumentFile tarVioDir = DocumentFile.fromTreeUri(this, targetVioUri);
            DocumentFile tarDir = null;

            if (fileName.contains("mp4") && (null == tarVioDir || !tarVioDir.exists())){
                showToast("V端无效！");
                return;
            }
            if ((fileName.contains("jpg") || fileName.contains("png")) && (null == tarPicDir || !tarPicDir.exists())){
                showToast("P端无效！");
                return;
            }

            if(fileName.contains("mp4")){
                tarDir = tarVioDir;
            }else if (fileName.contains("jpg") || fileName.contains("png")){
                tarDir = tarPicDir;
            }

            if (sourceDir == null || !sourceDir.exists()) {
                showToast("源端无效！");
                return;
            }

            DocumentFile sourceFile = sourceDir.findFile(fileName);
            if (sourceFile == null || !sourceFile.exists() || !sourceFile.isFile()) {
                Log.e(TAG, "源不存在: " + fileName);
                return;
            }


            String fileTime = getFileTime(fileName);
            String fileDay = fileTime.substring(0,8);
            String fileHour = fileTime.substring(0,10);
            String fileMin = fileTime.substring(0,12);

            Date fileDate = fmt.parse(fileTime);

            if (!isDateInRange(fileDate,tenMinutesAgoDate,nowDate)){
                return;
            }

            fileName = fileName.substring(3,fileName.length() - 1);

            // 检查目标文件是否已存在
            DocumentFile destFile = tarDir.findFile(fileName);
            if (destFile != null && destFile.exists()) {
                Log.i(TAG, "目标文件已存在: " + fileName);
                return;
            }

            // 创建目标文件
            destFile = tarDir.createFile(getMimeType(fileName), fileName);
            if (destFile == null) {
//                showToast("无法创建目标文件");
                return;
            }

            // 复制文件内容（适配一加手机的文件读写机制）
            try (InputStream in = getContentResolver().openInputStream(sourceFile.getUri());
                 OutputStream out = getContentResolver().openOutputStream(destFile.getUri())) {
                
                if (in == null || out == null) {
//                    showToast("无法访问文件流");
                    return;
                }

                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
                
//                showToast("已复制新文件: " + fileName);
                Log.i(TAG, "文件复制成功: " + fileName);
            }

        } catch (FileNotFoundException e) {
            Log.e(TAG, "文件未找到: " + e.getMessage());
//            showToast("文件未找到: " + fileName);
        } catch (IOException e) {
            Log.e(TAG, "文件复制错误: " + e.getMessage());
//            showToast("复制失败: " + fileName);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    public String getFileTime(String fileName){
        int lastDotIndex = fileName.lastIndexOf('.');
        fileName = lastDotIndex != -1 ? fileName.substring(0, lastDotIndex) : fileName;
        Pattern NON_DIGIT_PATTERN = Pattern.compile("[^0-9]");
        String fileTime = fileName;
        return NON_DIGIT_PATTERN.matcher(fileTime).replaceAll("");
    }

    public static boolean isDateInRange(Date target, Date start, Date end) {
        // 空值检查
        if (target == null || start == null || end == null) {
            throw new IllegalArgumentException("日期参数不能为null");
        }

        // 获取时间戳（毫秒数）
        long targetTime = target.getTime();
        long startTime = start.getTime();
        long endTime = end.getTime();

        // 确保开始时间不晚于结束时间
        if (startTime > endTime) {
            Date temp = start;
            start = end;
            end = temp;
            startTime = start.getTime();
            endTime = end.getTime();
        }

        // 检查是否在范围内（包含边界）
        return targetTime >= startTime && targetTime <= endTime;
    }

    private String getMimeType(String fileName) {
        int lastDot = fileName.lastIndexOf('.');
        if (lastDot > 0) {
            String extension = fileName.substring(lastDot + 1).toLowerCase();
            switch (extension) {
                case "jpg":
                case "jpeg":
                    return "image/jpeg";
                case "png":
                    return "image/png";
                case "pdf":
                    return "application/pdf";
                case "txt":
                    return "text/plain";
                default:
                    return "application/octet-stream";
            }
        }
        return "application/octet-stream";
    }

    private void showToast(String message) {
        handler.post(() -> Toast.makeText(FileMonitorService.this, message, Toast.LENGTH_SHORT).show());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (scheduler != null) {
            scheduler.shutdown();
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
    